namespace :fragment do
  TEMP_DIR = File.join(RAILS_ROOT, 'tmp', 'backup')
  IMAGE_DIR = File.join(Rails.public_path, 'images', 'jobs')
  DB_DUMP_FILENAME = "db.dump"
 
  desc "Backup database and fragment image directories."
  task :backup => :environment do
    db_config = ActiveRecord::Base.configurations[RAILS_ENV]
    raise "Only postgresql database adapter is supported" unless db_config['adapter'] == 'postgresql'
    
    backup_dir = APP_CONFIG['backup_dir'].starts_with?("/") ? APP_CONFIG['backup_dir'] : File.join(RAILS_ROOT, APP_CONFIG['backup_dir'])
    db_dump_file = File.join(TEMP_DIR, DB_DUMP_FILENAME)
    backup_file = File.join(backup_dir, "#{db_config['database']}_backup_#{Time.now.strftime('%Y%m%d-%H%M')}.tar.bz2")
    
    # Create directories if they don't exist.
    FileUtils.mkdir_p(backup_dir) unless File.exists? backup_dir
    FileUtils.mkdir_p(TEMP_DIR) unless File.exists? TEMP_DIR

    # Dump database.
    puts "Dumping batabase to #{db_dump_file}"
    cmd = "PGPASSWORD=#{db_config[:password]} && pg_dump -F c -b -w -U #{db_config['username']} -f #{db_dump_file} #{db_config['database']}"
    `#{cmd}`

    # Symlink image directory to temporary directory to simplify tarballing.
    FileUtils.ln_s(IMAGE_DIR, TEMP_DIR)

    # Archive database dump and image directory.
    puts "Compressing backup to #{backup_file} (this may take several minutes)."
    cmd = "cd #{TEMP_DIR} && tar cjhf #{backup_file} #{DB_DUMP_FILENAME} jobs"
    `#{cmd}`
    puts "Done, cleaning up."
    # Clean up afterwards.
    FileUtils.safe_unlink(File.join(TEMP_DIR, 'jobs'))
    FileUtils.remove_dir TEMP_DIR
    puts "All done."
  end

  desc "Restore database and fragment images from a backup."
  task :restore, :file, :needs => :environment do |t, args|
    db_config = ActiveRecord::Base.configurations[RAILS_ENV]
    raise "Only postgresql database adapter is supported" unless db_config['adapter'] == 'postgresql'

    backup_dir = APP_CONFIG['backup_dir'].starts_with?("/") ? APP_CONFIG['backup_dir'] : File.join(RAILS_ROOT, APP_CONFIG['backup_dir'])
    backup_file = args.file.nil? ? Dir["#{backup_dir}/#{db_config['database']}*.tar.bz2"].sort.last : args.file
    db_dump_file = File.join(TEMP_DIR, DB_DUMP_FILENAME)
    image_dir = File.join(TEMP_DIR, 'jobs')

    # Create temp dir if it doesn't exist.
    FileUtils.mkdir_p(TEMP_DIR) unless File.exists? TEMP_DIR

    # Extract archive.
    puts "Extracting backup data from #{backup_file} to #{TEMP_DIR} (this may take several minutes)."
    cmd = "tar xjf #{backup_file} -C #{TEMP_DIR}"
    `#{cmd}`

    # Restore database.
    puts "Restoring database from #{db_dump_file}"
    cmd = "PGPASSWORD=#{db_config[:password]} && pg_restore -F c -c -w -U #{db_config['username']} -d #{db_config['database']} #{db_dump_file}"
    `#{cmd}`

    # Replace image directory.
    puts "Restoring images to #{Rails.public_path}/images/jobs/."
    FileUtils.remove_dir IMAGE_DIR if File.exists? IMAGE_DIR
    FileUtils.cp_r(image_dir, File.join(Rails.public_path, 'images'))

    puts "Done, cleaning up."
    # Clean up afterwards
    FileUtils.remove_dir TEMP_DIR
    puts "All done."
  end
end

